/*
 * Copyright 2009 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.core.ext.js;

import java.io.Serializable;
import java.util.List;
import java.util.Set;

/**
 * The JavaScript AST representation of a JSNI method.
 */
public abstract class JsniFunction implements Serializable {

  /**
   * A parameter that belongs to an enclosing {@link JsniFunction}.
   */
  public abstract static class JsniParameter {
    /**
     * Returns the name of this parameter.
     */
    public abstract String getName();

    /**
     * Returns <code>true</code> if this parameter is referenced from the
     * enclosing function's code.
     */
    public abstract boolean isReferenced();
  }

  /**
   * Transform this JsniFunction so that it no longer depends on
   * <code>this</code> references. Specifically, the following changes must be
   * performed:
   * <ol>
   * <li>A new parameter is added at index 0</li>
   * <li>All references to <code>this</code> in the original method are
   * replaced with references to the new parameter instead</li>
   * </ol>
   */
  public abstract void convertToStatic();

  /**
   * Returns the list of all Java references found in this JSNI function. This
   * method must be implemented to be fast, because it might be called
   * frequently. The returned set may be immutable.
   */
  public abstract List<JavaRef> getJavaRefs();

  /**
   * Returns a list representing the parameters to this function. The list may
   * be a snapshot and does not need to be perpetually updated to reflect
   * changes to the underlying representation. In particular, calls to
   * {@link #convertToStatic()} and {@link #pruneParameters(List)} are expected
   * to invalidate the returned list. The returned list may be immutable.
   */
  public abstract List<JsniParameter> getParameters();

  /**
   * Returns the set of all string literals found in this JSNI function. This
   * method must be implemented to be fast, because it might be called
   * frequently. The returned set may be immutable.
   */
  public abstract Set<String> getStringLiterals();

  /**
   * Remove a list of parameters from this function. Each parameter in this list
   * is guaranteed to have been returned by the last call to
   * {@link #getParameters()}, and each parameter will have answered
   * <code>false</code> to {@link JsniParameter#isReferenced()}.
   */
  public abstract void pruneParameters(List<JsniParameter> parametersToPrune);
}
